﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using WinFromMediaPlayerDemo.Model;
using WinFromMediaPlayerDemo.Model.EventArgs;

namespace WinFromMediaPlayerDemo.Common
{
    /// <summary>
    /// 单文件下载
    /// </summary>
    public class SingleFileDownload
    {
        /// <summary>
        /// 文件下载进度改变事件
        /// </summary>
        public event EventHandler<FileDownloadProgressChangedEventArgts> FileDownloadProgressChanged;
        /// <summary>
        /// 所有文件下载完毕事件
        /// </summary>

        public event EventHandler TotalFilesDownloadCompleted;
        /// <summary>
        /// 下载地址
        /// </summary>

        public string BaseDownloadUrl { get; private set; }
        /// <summary>
        /// 文件保存目录
        /// </summary>
        public string FileSavedDirecotry { get; private set; }
        /// <summary>
        /// 文件队列中的总字节数
        /// </summary>

        public ulong TotalFileSize { get; private set; } = 0;
        /// <summary>
        /// 已接收字节数
        /// </summary>

        public ulong ReceivedBytesCount { get; private set; } = 0;

        /// <summary>
        /// 正在接收的字节数
        /// </summary>
        public ulong ReceivingBytesCount { get; private set; } = 0;
        /// <summary>
        /// 文件队列
        /// </summary>

        public ConcurrentQueue<RemoteFileInfo> Files { get; private set; }
        public SingleFileDownload(string fileSavedDirectory,string baseUrl, ConcurrentQueue<RemoteFileInfo> fileInfos)
        {
            this.FileSavedDirecotry = fileSavedDirectory;
            this.BaseDownloadUrl = baseUrl;
            this.Files = fileInfos;
            this.FileCount = (uint)Files.Count;
            foreach (var item in this.Files)
            {
                TotalFileSize += item.FileSize;
            }
        }
        public uint FileCount { get; private set; }



        public bool DownloadFile()
        {
            if(Files.IsEmpty)
            {
                return false;
            }
            RemoteFileInfo remoteFile;
            bool result = Files.TryDequeue(out remoteFile);
            if(!result)
            {
                return false;
            }

            using (WebClient client = new WebClient())
            {
                    
                //Console.WriteLine($"{currentFileInfo.FileName}===={requestFileSize}");
                Uri downUri = new Uri($"{BaseDownloadUrl}?fileName={remoteFile.FileName}");
                string fileSavedName = remoteFile.FileName;
                    
                client.DownloadFileCompleted += Client_DownloadFileCompleted;
                client.DownloadProgressChanged += Client_DownloadProgressChanged;
                client.DownloadFileAsync(downUri,System.IO.Path.Combine(FileSavedDirecotry, fileSavedName),remoteFile);
            }
            return true;
        
        }

        private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            //正在接收的字节数
            this.ReceivingBytesCount = (ulong)e.BytesReceived;
            RemoteFileInfo fileInfo = e.UserState as RemoteFileInfo;
            if(fileInfo == null)
            {
                return;
            }
            FileDownloadProgressChanged?.Invoke(this, new FileDownloadProgressChangedEventArgts()
            {
                CurrentPercentage = (byte)(Math.Floor(e.BytesReceived/(decimal)e.TotalBytesToReceive*100)),
                TotalPercentage = (byte)(Math.Floor((ReceivedBytesCount+ReceivingBytesCount) / (decimal)TotalFileSize*100)),
                FileInfo = fileInfo
            });
        }

        private void Client_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            RemoteFileInfo fileInfo = e.UserState as RemoteFileInfo;
            if(fileInfo == null)
            {
                return;
            }
            //已接收的字节数
            this.ReceivedBytesCount += fileInfo.FileSize;
            if (Files.IsEmpty)
            {
                TotalFilesDownloadCompleted?.Invoke(this, new EventArgs());
                return;
            }
            DownloadFile();
        }
    }
}
